package com.issc.framework.helper;

import com.issc.framework.bean.FileParam;
import com.issc.framework.bean.FormParam;
import com.issc.framework.bean.Param;
import com.issc.framework.util.FileUtil;
import com.issc.framework.util.StreamUtil;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

public class FileUploadHelper {

    private static ServletFileUpload servletFileUpload;

    public static void init(ServletContext servletContext) {
        File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
        servletFileUpload = new ServletFileUpload(new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD, repository));
        int uploadLimit = ConfigHelper.getAppUploadLimit();
        if (uploadLimit != 0) {
            servletFileUpload.setFileSizeMax(uploadLimit * 1024 * 1024);
        }
    }

    public static Param createParam(HttpServletRequest request)  {
        List<FileParam> fileParamList = new ArrayList<>();
        List<FormParam> formParamList = new ArrayList<>();
        try {
            Map<String, List<FileItem>> fileItemListMap = servletFileUpload.parseParameterMap(request);
            if (fileItemListMap != null && !fileItemListMap.isEmpty()) {
                for (Map.Entry<String, List<FileItem>> fileItemMap : fileItemListMap.entrySet()) {
                    String fieldName = fileItemMap.getKey();
                    List<FileItem> fileItemList = fileItemMap.getValue();
                    if (!fileItemList.isEmpty()) {
                        for (FileItem fileItem : fileItemList) {
                            if (fileItem.isFormField()) {
                                String fieldValue = fileItem.getString("UTF-8");
                                formParamList.add(new FormParam(fieldName, fieldValue));
                            } else {
                                //获取真实文件名
                                String fileName = FilenameUtils.getName(new String((fileItem.getName().getBytes()), "UTF-8"));
                                if (StringUtils.isNotEmpty(fieldName)) {
                                    long size = fileItem.getSize();
                                    String contentType = fileItem.getContentType();
                                    InputStream inputStream = fileItem.getInputStream();
                                    fileParamList.add(new FileParam(fieldName, fileName, size, contentType, inputStream));
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Param(fileParamList, formParamList);
    }

    public static Param getParam(HttpServletRequest req) throws IOException {
        Map<String, Object> paramMap = new HashMap<>();
        //获取输入实参的名字
        Enumeration<String> parameterNames = req.getParameterNames();
        //如果有参数
        while (parameterNames.hasMoreElements()) {
            String paramName = parameterNames.nextElement();
            String paramValue = req.getParameter(paramName);
            paramMap.put(paramName, paramValue);
        }
        //获取body里的参数，并转换成字符串的形式
        String body = StreamUtil.getString(req.getInputStream());
        if (!body.isEmpty()) {
            //把“&”符号两边的字符串分别截取为单个字符串放入数组中
            String[] params = StringUtils.split(body, "&");
            if (ArrayUtils.isNotEmpty(params)) {
                for (String oneParam : params) {
                    //把“=”符号两边的字符串分别截取放入数组中
                    String[] array = StringUtils.split(oneParam, "=");
                    //判断数组是否为空并且长度是否为2 （key,value）
                    if (ArrayUtils.isNotEmpty(array) && array.length == 2) {
                        String paramName = array[0];
                        String paramValue = array[1];
                        paramMap.put(paramName, paramValue);
                    }
                }
            }
        }
        return new Param(paramMap);
    }

    public static void uploadFile(String basePath, FileParam fileParam) throws UnsupportedEncodingException {
        String path = basePath + fileParam.getFileName();
        FileUtil.createFile(path);
        try (BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(path));
             InputStream inputStream = fileParam.getInputStream()) {
            byte[] bytes = new byte[1024];
            while (inputStream.read(bytes) != -1) {
                outputStream.write(bytes);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void uploadFile(String basePath, List<FileParam> fileParams) {
        try {
            if (!fileParams.isEmpty()) {
                for (FileParam fileParam : fileParams) {
                    uploadFile(basePath, fileParam);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
